import pandas as pd
from flask import Blueprint, request, current_app
from app.service.decision_service import DecisionService
from app.service.backtest_service import BacktestService
from app.utils import success, error
from app.models import db, User, Preference
from app.service.stock_service import fetch_stock_list_from_sina
from app.service.model_service import train_and_predict
import app.utils as utils
from flask_jwt_extended import jwt_required, get_jwt_identity

portfolio_controller = Blueprint('portfolio', __name__)
tickers = pd.DataFrame()
default_portfolio = []

@portfolio_controller.post('/recommend')
@jwt_required()
def get_recommendation():
    """
    获取个性化投资组合推荐
    """
    try:
        print("------enter")
        user_id = get_jwt_identity()
        if not user_id:
            return error("用户状态异常", status=400,code=1)
        db_user = db.session.query(User).filter_by(id=user_id).first()
        # current_app.logger("recommend")
        print("-----user")
        print(db_user.id)
        try:
            print('开始存入数据库')
            global tickers
            tickers = fetch_stock_list_from_sina()
            print("----ticker")
            print(tickers.head())
        except Exception as e:
            return utils.error("股票数据更新失败", status=500, code=1)
        try:
            pred = train_and_predict(tickers)
            print(pred[:2])
        except Exception as e:
            return utils.error("预测失败", status=500, code=1)
        try:
            service = DecisionService()
            global default_portfolio
            default_portfolio = service.get_recommendation_id(user_id, pred)
            if not default_portfolio:
                return error("暂无合适推荐", status=404,code=1)

            return utils.success(data={
                "risk_based_portfolio": default_portfolio,
                "message": "根据您的风险偏好生成"
            })
        except Exception as e:
            return error(f"推荐失败: {str(e)}", status=500,code=1)
    except Exception as e:
        return error(f"推荐失败: {str(e)}", status=500, code=1)

@portfolio_controller.post('/backtest')
@jwt_required()
def get_backtest_portfolio():
    """
    回测推荐组合收益情况
    需要传入 portfolio（包含 ticker 和 weight）及 start_date 和 end_date
    """
    print("-----back")
    try:
        user_id = get_jwt_identity()
        if not user_id:
            return error("用户状态异常", status=400, code=1)
        db_user = db.session.query(User).filter_by(id=user_id).first()
        print("----id")
        print(db_user.id)
        data = request.get_json()
        print("-------port")
        print(default_portfolio)
        if not default_portfolio :
            return utils.error(message="您还未生成策略",status=500,code=1)
        medium_risk_portfolio = next(
            (item['portfolio'] for item in default_portfolio if item['risk_level'] == '中等风险推荐'),
            []
        )
        portfolio = medium_risk_portfolio
        print("-----中等")
        print(portfolio)
        start_date = data.get("start_date")
        print("----start_date")
        print(start_date)
        end_date = data.get("end_date")
        print("----end_date")
        print(end_date)

        if not portfolio or not start_date or not end_date:
            return error("缺少参数", status=400, code=1)

        global tickers
        print("----ticker")
        print(tickers.head())
        if tickers.empty:
            print("000")
            try:
                print('开始存入数据库')
                tickers = fetch_stock_list_from_sina()
            except Exception as e:
                return utils.error("股票数据更新失败", status=500, code=1)
        print("-----begin")
        service = BacktestService()
        result = service.backtest_portfolio(portfolio, start_date, end_date, tickers)
        print("---result")
        print(result)
        if not result:
            return error("回测失败：数据不足或推荐为空", status=404, code=1)

        return success(data=result)

    except Exception as e:
        return error(f"回测失败: {str(e)}", status=500, code=1)
